﻿using LF.Common;
using LF.Domain.Entities;
using LF.Domain.Helper;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static LF.Common.AppConfig;

namespace LF.Domain.Services.Iml
{
    public class AppManagerService : IAppManagerService
    {
        /// <summary>
        /// 初始化系统管理员账号和所有权限
        /// </summary>
        /// <returns>成功创建返回true，已存在返回false</returns>
        public bool InitializeSysAdmin()
        {
            // 检查是否已存在sysadmin用户
            var sysAdmin = FreeSqlHelper.DbContext.Queryable<User>()
                .Where(u => u.UserName == "sysadmin" && !u.IsDelete)
                .First();

            if (sysAdmin != null)
            {
                return false; // 用户已存在，不需要创建
            }

            bool success = false;
            FreeSqlHelper.DbContext.Transaction(() =>
            {
                try
                {
                    // 1. 创建系统管理员角色
                    var adminRole = new Role
                    {
                        Id = Guid.NewGuid(),
                        Name = "系统管理员",
                        Status = 1, // 启用
                        Remark = "系统内置管理员角色，拥有所有权限",
                        CreatTime = DateTime.Now,
                        UpdateTime = DateTime.Now
                    };
                    
                    FreeSqlHelper.DbContext.Insert(adminRole).ExecuteAffrows();

                    // 2. 创建sysadmin用户
                    sysAdmin = new User
                    {
                        Id = Guid.NewGuid(),
                        UserName = "sysadmin",
                        RealName = "系统管理员",
                        Mobile = "",
                        Password = "123456".ToFastMd5(), // 默认密码
                        Active = true,
                        CreatTime = DateTime.Now,
                        UpdateTime = DateTime.Now
                    };
                    
                    FreeSqlHelper.DbContext.Insert(sysAdmin).ExecuteAffrows();

                    // 3. 给用户分配管理员角色
                    var userRole = new UserRole
                    {
                        Id = Guid.NewGuid(),
                        UserId = sysAdmin.Id,
                        RoleId = adminRole.Id,
                        CreatTime = DateTime.Now,
                        UpdateTime = DateTime.Now
                    };
                    
                    FreeSqlHelper.DbContext.Insert(userRole).ExecuteAffrows();

                    success = true;
                }
                catch
                {
                    success = false;
                    throw;
                }
            });

            return success;
        }

        public bool AddLog(AppLog log)
        {
            var result = FreeSqlHelper.DbContext.Insert(log).ExecuteAffrows();

            return result > 0;
        }

        public List<User> AllUser(int index, int size, string key)
        {
            var query = FreeSqlHelper.DbContext.Queryable<User>();
            if (!key.IsNullOrWhiteSpace())
            {
                query = query.Where(p => p.RealName.Contains(key)
                || p.UserName.Contains(key));
            }
            var list = query.OrderByDescending(p => p.CreatTime)
                    .Page(index, size)
                    .ToList();
            return list;
        }

        public long AllUserCount(int index, int size, string key)
        {
            var query = FreeSqlHelper.DbContext.Queryable<User>();
            if (!key.IsNullOrWhiteSpace())
            {
                query = query.Where(p => p.RealName.Contains(key)
                || p.UserName.Contains(key));
            }
            var list = query.Count();
            return list;
        }

        public AppDic[] GetAppDic(string group)
        {
            var appConfig = FreeSqlHelper.DbContext.Queryable<AppDic>()
                .Where(c => c.Group == group)
                .OrderBy(p => p.Order)
                .ToList();

            return appConfig.ToArray();
        }

        public List<AppDic> GetAppDic(int index, int size)
        {
            var appConfig = FreeSqlHelper.DbContext.Queryable<AppDic>()
                .OrderBy(p => p.Order)
                .Page(index, size).ToList();

            return appConfig;
        }

        public List<AppDic> GetAppDic(int index, int size, string key)
        {
            var appConfig = FreeSqlHelper.DbContext.Queryable<AppDic>().Where(
            p => p.Group.Contains(key)
            ||
            p.Desc != null && p.Desc.Contains("key")
            )
            .OrderBy(p => p.Order)
            .Page(index, size).ToList();

            return appConfig;
        }

        public AppDic[] GetAppDic()
        {
            var appConfig = FreeSqlHelper.DbContext.Queryable<AppDic>()
                .OrderBy(p => p.Order)
                .ToList()
                .ToArray();
            return appConfig;
        }

        public string? GetConfig(string key)
        {
            var config = FreeSqlHelper.DbContext.Queryable<Config>()
                .Where(p => p.Key == key)
                .First();
            return config?.Value;
        }

    

        public SysFile GetFile(string md5)
        {
            var result = FreeSqlHelper.DbContext.Queryable<SysFile>().Where(p=>p.Md5==md5).First();
            return result;
        }

        public long GetNoticeCount()
        {
            var count = FreeSqlHelper.DbContext.Queryable<Notice>().Count();
            return count;
        }

        public List<Notice> GetNotices(int index, int size, string key)
        {
            var query = FreeSqlHelper.DbContext.Queryable<Notice>();
            if (!key.IsNullOrWhiteSpace())
            {
                query = query.Where(p => p.Content.Contains(key));
            }
            var list = query.OrderByDescending(p => p.CreatTime)
                    .Page(index, size)
                    .ToList();
            return list;
        }

        public List<Notice> GetNotices(int index, int size, DateOnly date)
        {
            var query = FreeSqlHelper.DbContext.Queryable<Notice>().Where(p => p.ActiveDate >= date);
            var list = query.OrderByDescending(p => p.CreatTime)
                    .Page(index, size)
                    .ToList();
            return list;
        }

        public Rule GetRule()
        {
            var rule = FreeSqlHelper.DbContext.Queryable<Rule>().First();
            return rule;
        }

        public User GetUser(string userName)
        {
            var user = FreeSqlHelper.DbContext.Queryable<User>()
                .Where(p => p.Active && p.UserName == userName)
                .First();
            return user;
        }

        public User GetOldUser(string userName)
        {
            var user = FreeSqlHelper.DbContext.Queryable<User>()
                .Where(p => p.UserName == userName)
                .First();
            return user;
        }

        public bool Insert(SysFile file)
        {
            var sysfile = GetFile(file.Md5);
            //文件存在更新最后操作者
            if (sysfile != null)
            {
                sysfile.UserId = file.UserId;
                FreeSqlHelper.DbContext.Update<SysFile>(file.Id).SetSource(sysfile);
                return true;
            }
            var size = FreeSqlHelper.DbContext.Insert(file).ExecuteAffrows();
            return size > 0;
        }

     
        public bool InsertNotice(Notice notice)
        {
            var size = FreeSqlHelper.DbContext.Insert(notice).ExecuteAffrows();
            return size > 0;
        }

        public Rule InsertOrUpdate(Rule rule)
        {
            Rule? result;
            var any = FreeSqlHelper.DbContext.Queryable<Rule>().Any();
            if (any)
            {
                rule.UpdateTime = DateTime.Now;
                FreeSqlHelper.DbContext.Update<Rule>(rule.Id)
                    .SetSource(rule)
                    .IgnoreColumns(p => new { p.CreatTime})//, p.RegisterStart, p.RegisterEnd 
                    .ExecuteAffrows();
                result = GetRule();
                return result;

            }
            else
            {
                rule.CreatTime = DateTime.Now;
                FreeSqlHelper.DbContext.Insert(rule).ExecuteAffrows();
                result = GetRule();
                return result;
            }
        }


        public bool UpdateNotice(Notice notice)
        {
            var size = FreeSqlHelper.DbContext.Update<Notice>(notice.Id)
               .SetSource(notice)
               .IgnoreColumns(p => new { p.CreatTime })
               .ExecuteAffrows();
            return size > 0;
        }
    }
}
